
import { remote } from "electron";


import { IO, Tile, Adapter, BitMath, App } from "./letusbit/lib.letusbit/lib";






function createRootCanvas(): CanvasRenderingContext2D
{
    let canvas = document.createElement("canvas");

    document.body.append(canvas);
    canvas.style.width = "100%";
    canvas.style.height = "100%";
    let canvasContextRoot = canvas.getContext("2d");
    if (canvasContextRoot == null)
        throw new Error("not allow null");
    canvasContextRoot.imageSmoothingEnabled = false;
    let viewwidth = 200;
    let heightradio = document.body.clientHeight / document.body.clientWidth;
    let viewheight = viewwidth * heightradio;

    document.body.onresize = () =>
    {
        let heightradio = document.body.clientHeight / document.body.clientWidth;
        viewwidth = 200;
        viewheight = viewwidth * heightradio;
        canvas.width = viewwidth;
        canvas.height = viewheight;
    }
    viewwidth = 200;
    viewheight = viewwidth * heightradio;
    canvas.width = viewwidth;
    canvas.height = viewheight;
    return canvasContextRoot;
}
function delay(ms: number)
{
    return new Promise<void>(function (resolve)
    {
        setTimeout(resolve, ms);
    });
}

async function loadBin(url: string): Promise<ArrayBuffer | null>
{

    var ab = await (await fetch(url)).arrayBuffer();

    return ab;
}
async function loadImage(url: string): Promise<HTMLImageElement | null>
{
    let rimg: HTMLImageElement | null = null;
    let img = new Image();
    let end = false;
    img.onload = () =>
    {
        rimg = img;
        end = true;
    }
    img.onerror = () =>
    {
        rimg = null;
        end = true;
    }
    img.src = url;
    while (!end)
        await delay(1);
    return rimg;
}


class MyCode implements App.IUserCode
{
    bank?:Tile.Bank;
    img: HTMLImageElement | null = null;
    cameray: number = 0;
    async OnInit(app: App.IFramework): Promise<void>
    {
        let palette = Tile.TileTool.GetNesPalette();

            this.bank = app.render ? new Tile.Bank(palette, app.render) : undefined;
        if (this.bank)
        {
            this.img = await loadImage("dist/images/bg.jpg");
            let buf = new Uint8Array(3);
            let br = new IO.binReader(buf.buffer, 0);
            console.warn("hello world.");
            console.log("test go.");
            //wx.showModal({ "title": "hi", content: "lalal" })
            //this.SetBackAudio("dist/audio/bgm.mp3");

            this.bank.RegTileData("block", Tile.TileTool.GenBlock());

            //装载12号ASCII字体
            var fileASCII = await loadBin("dist/zkbin/ASC12.bin");
            if (fileASCII == null)
                throw new Error("load error");
            Tile.TileTool.LoadASCII12toBank(new Uint8Array(fileASCII), this.bank);

            //utf16->gb2312的转换码表，因为我们用的是个12点阵的GB2312汉字库 ，来自UCDOS
            var fileHzkConv = await loadBin("dist/zkbin/UTF16CONV.bin");
            var fileHzk = await loadBin("dist/zkbin/HZK12.bin");
            if (fileHzkConv == null)
                throw new Error("load error");
            if (fileHzk == null)
                throw new Error("load error");
            Tile.TileTool.LoadHZK12toBank(new Uint8Array(fileHzk), new Uint8Array(fileHzkConv), this.bank);
        }
    }
    OnUpdate(app: App.IFramework): void
    {
        if (this.img != null)
        {

            //做一个循环屏幕填充
            let imgrh = this.img.height / this.img.width * (app.render?.viewwidth ?? 0);

            let starty = this.cameray % imgrh;
            while (starty > 0)
                starty -= imgrh;
            while (starty < (app.render?.viewheight ?? 0))
            {
                var srcr = new BitMath.Rect(0, 0, this.img.width, this.img.height);
                app.render?.Draw(this.img, srcr,
                    0, starty, 0);
                starty += imgrh;
                //console.log("starty=" + starty);
            }
        }
        //移动相机
        this.cameray += 2;

        var block = this.bank?.GetTileByName("block");
        if (block != null)
        {
            app.render?.DrawScale(block.tex, block.srcrect, new BitMath.Rect(0, 0, 32, 32), 0);
        }
        let hstr = "武汉加油！小兄弟？hello world..";
        let x = 0;
        let y = 32;
        for (var i = 0; i < hstr.length; i++)
        {
            var s = this.bank?.GetTileByName(hstr.charAt(i));
            if (s != null)
            {
                app.render?.Draw(s.tex, s.srcrect, x, y, 0);
                x += s.srcrect.w;
            }
        }
    }
}


window.onload = () =>
{


    let canvasContextRoot = createRootCanvas();


    //this.canvasContextRoot = canvasRoot.getContext("2d") as CanvasRenderingContext2D;

    let render_adapter = Adapter.CreateWebCanvasAdapter(canvasContextRoot, (w, h) =>
    {
        var canvas = new OffscreenCanvas(w, h);
        let con = canvas.getContext("2d");
        if (con == null)
            throw new Error("fail to create OffscreenCanvas");
        return con;
    });

    let mycode = new MyCode();

    let app = new App.Framework(mycode, render_adapter, null);
    app.Init();


}